defmodule IocpMonitor.Worker.TimeAdjustment do
  @moduledoc """
  给特定电流盒子定时发送对时包的进程定义模块
  """

  require Logger

  use GenServer
  use IocpMonitor.Types

  alias IocpMonitor.Sender
  alias IocpMonitor.DeviceAddressHolders
  alias IocpMonitor.Worker.DeviceAddressHolder

  @spec start_link({tcp_client(), pid()}) :: :ok | {:error, term()}
  def start_link({_client, _sup} = state) do
    GenServer.start_link(__MODULE__, state)
  end

  @impl true
  def init(state) do
    Process.send_after(self(), :schedule, 2_000)
    {:ok, state}
  end

  @impl true
  def handle_info(:schedule, {client, sup} = state) do
    Process.send_after(self(), :schedule, 86400_000)
    Sender.adjust_time!(client, get_device_address(sup))
    {:noreply, state}
  end

  def handle_info(_, state), do: {:noreply, state}

  @impl true
  def terminate(reason, {client, sup}) do
    :gen_tcp.close(client)
    IocpMonitor.Client.Supervisor.terminate_child(sup)
  end

  @doc false
  def child_spec(arg) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [arg]},
      type: :worker,
      restart: :temporary,
      shutdown: 500
    }
  end

  defp get_device_address(sup) do
    [{device_address_holder, _}] = Registry.lookup(DeviceAddressHolders, sup)
    DeviceAddressHolder.get(device_address_holder)
  end
end
